package com.xqboss.apps.service.guild;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqboss.apps.domain.guild.Guild;
import com.xqboss.apps.domain.guild.GuildApplyRecord;
import com.xqboss.apps.domain.guild.GuildInviteRecord;
import com.xqboss.apps.enums.guild.GuildApplyOrInviteStatusEnum;
import com.xqboss.apps.mapper.guild.GuildInviteRecordMapper;
import com.xqboss.apps.vo.guild.GuildInviteMeRecordVo;
import com.xqboss.common.exception.ServiceException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 公会邀请记录表——会长操作(GuildInviteRecord)表服务实现类
 *
 *
 * @author LJH
 * @since 2024-01-09 17:21:10
 */
@Service
public class GuildInviteRecordService extends ServiceImpl<GuildInviteRecordMapper, GuildInviteRecord> {

    /**
     * 获取邀请我的公会记录
     *
     * @param userId 用户id
     * @return 邀请我的
     */
    public IPage<GuildInviteMeRecordVo> getInviteMeRecordVo(Page<GuildInviteMeRecordVo> page, Long userId) {
        Assert.notNull(userId,()->new ServiceException("用户id不能为空！"));
        return this.getBaseMapper().getInviteMeRecordVo(page,userId);
    }

    /**
     * 修改邀请状态
     *
     * @param guildId 邀请的公会id
     * @param userId 被邀请的用户id
     * @param status 要更新的邀请状态
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateInviteStatus(Long guildId, Long userId, GuildApplyOrInviteStatusEnum status) {
        Assert.notNull(guildId,()->new ServiceException("公会id不能为空！"));
        Assert.notNull(userId,()->new ServiceException("用户id不能为空！"));
        Assert.notNull(status,()->new ServiceException("邀请状态不能为空！"));
        int count = this.getBaseMapper().countInviteRecord(guildId,userId,GuildApplyOrInviteStatusEnum.APPROVED.getValue());
        Assert.isTrue(count!=0,()->new ServiceException("邀请记录不存在~"));
        boolean update = this.lambdaUpdate().set(GuildInviteRecord::getInviteStatus, status)
                .eq(GuildInviteRecord::getInviteGuildId, guildId)
                .eq(GuildInviteRecord::getInvitedUserId, userId)
                .eq(GuildInviteRecord::getInviteStatus, GuildApplyOrInviteStatusEnum.APPROVED)
                .update();
        Assert.isTrue(update,()->new ServiceException("邀请状态更新失败~"));
    }

    /**
     * 记录会长邀请会员的记录
     *
     * @param guildId 公会id
     * @param inviteUserId 邀请方用户id
     * @param invitedUserId 被邀请方用户id
     */
    @Transactional(rollbackFor = Exception.class)
    public void recordInvite(Long guildId, Long inviteUserId, Long invitedUserId) {
        Assert.notNull(guildId,()->new ServiceException("公会id不能为空！"));
        Assert.notNull(inviteUserId,()->new ServiceException("邀请方用户id不能为空！"));
        Assert.notNull(invitedUserId,()->new ServiceException("被邀请方用户id不能为空！"));
        GuildInviteRecord inviteRecord = this.lambdaQuery().eq(GuildInviteRecord::getInviteGuildId, guildId)
                .eq(GuildInviteRecord::getInvitedUserId, invitedUserId)
                .eq(GuildInviteRecord::getInviteStatus, GuildApplyOrInviteStatusEnum.APPROVED)
                .one();
        if (ObjUtil.isNotEmpty(inviteRecord)) {
            inviteRecord.setInviteUserId(inviteUserId);
            inviteRecord.setCreateTime(LocalDateTime.now());
            inviteRecord.setUpdateTime(LocalDateTime.now());
            boolean update = this.updateById(inviteRecord);
            Assert.isTrue(update,()->new ServiceException("重复邀请更新邀请记录失败~"));
            return;
        }
        inviteRecord = GuildInviteRecord.builder().inviteGuildId(guildId).inviteUserId(inviteUserId).invitedUserId(invitedUserId).inviteStatus(GuildApplyOrInviteStatusEnum.APPROVED).build();
        boolean save = this.save(inviteRecord);
        Assert.isTrue(save,()->new ServiceException("添加邀请记录失败~"));
    }


    /**
     * 已加入邀请我的公会。执行已超时-邀请我的其它公会
     *
     * @param userId 要加入邀请公会的用户id
     */
    @Transactional(rollbackFor = Exception.class)
    public void actionInviteTimeOutUser(Long userId) {
        Assert.notNull(userId,()->new ServiceException("用户id不能为空！"));
        // 先判断有无要修改的
        Long count = this.lambdaQuery()
                .eq(GuildInviteRecord::getInvitedUserId, userId)
                .eq(GuildInviteRecord::getInviteStatus, GuildApplyOrInviteStatusEnum.APPROVED)
                .count();
        if(count==0)return;
        // 批量修改邀请状态为已超时
        boolean update = this.lambdaUpdate()
                .set(GuildInviteRecord::getInviteStatus, GuildApplyOrInviteStatusEnum.TIMED_OUT)
                .eq(GuildInviteRecord::getInvitedUserId, userId)
                .eq(GuildInviteRecord::getInviteStatus, GuildApplyOrInviteStatusEnum.APPROVED)
                .update();
        Assert.isTrue(update,()->new ServiceException("邀请状态更新为已超时失败~"));
    }


    /**
     * 公会已满员 或 公会解散，那么该公会的所有邀请过的用户的邀请状态 修改为：已超时
     *
     * @param guildId 邀请了用户的公会id
     */
    @Transactional(rollbackFor = Exception.class)
    public void actionInviteTimeOutGuild(Long guildId) {
        Assert.notNull(guildId,()->new ServiceException("公会id不能为空！"));
        // 先判断有无要修改的
        Long count = this.lambdaQuery()
                .eq(GuildInviteRecord::getInviteGuildId, guildId)
                .eq(GuildInviteRecord::getInviteStatus, GuildApplyOrInviteStatusEnum.APPROVED)
                .count();
        if(count==0)return;
        // 批量修改邀请状态为已超时
        boolean update = this.lambdaUpdate()
                .set(GuildInviteRecord::getInviteStatus, GuildApplyOrInviteStatusEnum.TIMED_OUT)
                .eq(GuildInviteRecord::getInviteGuildId, guildId)
                .eq(GuildInviteRecord::getInviteStatus, GuildApplyOrInviteStatusEnum.APPROVED)
                .update();
        Assert.isTrue(update,()->new ServiceException("邀请状态更新为已超时失败~"));
    }
}

